package energy;

import java.util.*;
import java.util.concurrent.*;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class CalibrationDriver extends Thread {

	private static Logger log = Logger.getLogger("energy.Calibration");
	private static final int DELAY = 1000;
	private static final int PERIOD = 1000;
	
	private Driver<EnergyData> driver;
	private EnergyStorage storage;
	private Timer timer;
	private int wantedSamples;
	
	BlockingQueue<EnergyData> data;
	private int currentSamples;
	private boolean done;
	
	public CalibrationDriver(String path, int samples, String filename) {
		driver = new EnergyDriver(path);
		storage = new EnergyStorage(filename);
		timer = new Timer("Calibration Timer");
		wantedSamples = samples;
		data = new LinkedBlockingQueue<EnergyData>();
		currentSamples = 0;
		done = false;
		
		log.debug("Calibrating " + samples + " samples into a csv file called " + filename + ".csv");
	}
	
	public void run() {
		
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				
				for(EnergyData d : driver.getdata()) {
					try {
						data.put(d);
					} catch (InterruptedException e) {
						log.error("Timer interupted.");
						done = true;
					}	
				}
			}};
		timer.scheduleAtFixedRate(task, DELAY, PERIOD);
		
		if(!storage.open("Not Processed")) return;
		driver.init();
		driver.start();
		
		while(!done) {
			EnergyData d;
			
			try {
				d = data.take();
			} catch (InterruptedException e) {
				log.error("Calibration Interupted");
				done = true;
				continue;
			}
			log.debug(d);
			storage.add(d);
			currentSamples++;
			log.debug("" + ((double)currentSamples/(double)wantedSamples) * 100 + "%.");
			
			if(currentSamples>=wantedSamples) {
				done = true;
			}
		}
		
		timer.cancel();
		driver.stop();
		//driver.destroy();
		storage.close();
		
		System.exit(0); //TODO: only called cause source.close() from driver.destroy does not seem to work.
	}
		
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BasicConfigurator.configure();
        Logger.getRootLogger().setLevel(Level.DEBUG);
        
        if(args.length<4) {
        	log.error("\t Usage energy.Calibration <path_to_mote> <number_samples> <file_to_store_in>");
        	return;
        }
        
        int samples = 0;
        try {
        	samples = Integer.parseInt(args[1]);
        } catch(NumberFormatException e) {
        	log.error("No a valid sample number!");
        	return;
        }
        
		CalibrationDriver c = new CalibrationDriver(args[0], samples, args[2]);
		c.setName("Calibration");
		c.start();
		//c.join();
	}

}
